package controller

import (
	"admin/contrib/session"
	"admin/model"
	"common/helper"
	"encoding/json"
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	g "github.com/doug-martin/goqu/v9"
	"github.com/valyala/fasthttp"
	"io"
	"net/url"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

type ServiceController struct{}

type CustomServiceListParam struct {
	Nullity  string `json:"nullity"`
	JumpType string `json:"jump_type"`
	Page     uint   `json:"page" cbor:"page"`
	PageSize uint   `json:"page_size" cbor:"page_size"`
}

// 上下分审核
func (that *ServiceController) AdjustList(ctx *fasthttp.RequestCtx) {

	param := model.Adjustparam{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}
	param.IsOperator = ctx.QueryArgs().GetUintOrZero("is_operator")

	if param.Page < 1 {
		param.Page = 1
	}

	if param.PageSize < 10 || param.PageSize > 3000 {
		helper.RetData(ctx, false, "参数错误")
		return
	}

	data, err := model.AdjustList(param, ctx)
	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}

	helper.RetData(ctx, true, data)
}

type insertMemberAdjustParam struct {
	Uid         string `json:"uid" cbor:"uid" db:"uid"`
	Amount      string `json:"amount" cbor:"amount" db:"amount"`
	WagerTimes  int    `json:"wager_times" cbor:"wager_times" db:"wager_times"`
	AdjustMode  int    `json:"adjust_mode" cbor:"adjust_mode" db:"adjust_mode"`
	ApplyRemark string `json:"apply_remark" cbor:"apply_remark" db:"apply_remark"`
}

// Insert 会员列表-账户调整
func (that *ServiceController) AdjustInsert(ctx *fasthttp.RequestCtx) {

	param := insertMemberAdjustParam{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}
	model.InsertLog("玩家后台上分申请", ctx)

	amount, err := strconv.ParseFloat(param.Amount, 64)
	if err != nil {
		amount = 0
	}
	if amount <= 0 {
		helper.RetData(ctx, false, helper.AmountErr)
		return
	}
	// get member info
	userinfo, err := model.MemberFindByUid(param.Uid)
	if err != nil {
		helper.RetData(ctx, false, helper.UIDErr)
		return
	}

	auth, err := model.UserAuthCheck(userinfo, ctx)
	if auth == false || err != nil {
		helper.RetData(ctx, false, err)
		return
	}
	applyName := ""
	admin := session.AdminGet(ctx)
	if admin["loginuser"] == "business" {
		businessinfo, _ := model.GetBusinessInfoById(admin["id"])
		applyName = "operator:" + businessinfo.OperatorId + "-business:" + admin["id"]
	} else if admin["loginuser"] == "merchant" {
		applyName = "operator:" + admin["id"]
	} else {
		applyName = admin["name"]
	}
	if param.ApplyRemark != "" {
		param.ApplyRemark, _ = url.PathUnescape(param.ApplyRemark)
	}

	record := model.TblMemberAdjust{
		Id:          helper.GenId(),
		Uid:         userinfo.Uid,
		Username:    userinfo.Username,
		WagerTimes:  param.WagerTimes,
		AdjustMode:  param.AdjustMode,
		ApplyRemark: param.ApplyRemark,
		Amount:      amount,
		State:       1, // 状态:1=审核中,2=同意, 3=拒绝
		ApplyAt:     ctx.Time().Unix(),
		ApplyUid:    admin["id"], // 申请人
		ApplyName:   applyName,   // 申请人
		ReviewUid:   "0",
		Tester:      userinfo.Tester,
	}
	err = model.AdjustInsert(record, userinfo, admin["loginuser"])
	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	helper.RetData(ctx, true, "成功")
}

type reviewMemberAdjustParam struct {
	Id           string `json:"id"`
	State        string `json:"state"`
	ReviewRemark string `json:"review_remark"`
}

// GM上分审核
func (that *ServiceController) AdjustReview(ctx *fasthttp.RequestCtx) {

	param := reviewMemberAdjustParam{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}

	model.InsertLog("玩家后台上分审核", ctx)

	orderIds := []string{}
	if param.Id == "-1" {
		where := "state=" + model.AdjustReviewing
		loginUser := model.GetLoginUser(ctx)
		if loginUser.Operator != "" {
			where += " and apply_name like 'operator:" + loginUser.Operator + "%'"
		} else if loginUser.Businsess != "" {
			where += " and apply_name like '%-business:" + loginUser.Businsess + "'"
		} else {

		}
		orderIds = model.GetAdjustOrderIds(where)
	} else {
		orderIds = strings.Split(param.Id, ",")
	}

	if orderIds == nil || len(orderIds) == 0 {
		helper.RetData(ctx, false, helper.IDErr)
		return
	}
	if param.State != "2" && param.State != "3" {
		helper.RetData(ctx, false, "状态错误")
		return
	}

	if param.ReviewRemark != "" {
		param.ReviewRemark, _ = url.PathUnescape(param.ReviewRemark)
	}

	admin := session.AdminGet(ctx)
	if err != nil {
		helper.RetData(ctx, false, helper.AccessTokenExpires)
		return
	}

	successNum := 0
	failNum := 0
	for _, id := range orderIds {
		err = model.AdjustLock(id)
		if err != nil {
			failNum += 1
			continue
		}
		record := g.Record{
			"id":            id,
			"review_remark": param.ReviewRemark,
			"state":         param.State,
			"review_at":     ctx.Time().Unix(),
			"review_uid":    admin["id"],
			"review_name":   admin["name"],
		}
		err = model.AdjustReview(param.State, record)

		if err == nil {
			successNum += 1
		} else {
			failNum += 1
		}
		//解锁
		model.AdjustUnLock(id)
	}
	//err = model.AdjustReview(param.State, record)
	//if err != nil {
	//	helper.RetData(ctx, false, err.Error())
	//	return
	//}
	retData := make(map[string]int)
	retData["success_total"] = successNum
	retData["faild_total"] = failNum

	helper.RetData(ctx, true, retData)
	//helper.RetData(ctx, true, "成功")
}

// 后台日志
func (that *ServiceController) LogList(ctx *fasthttp.RequestCtx) {

	param := model.BackgroundLogParam{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}

	if param.Page < 1 {
		param.Page = 1
	}

	if param.PageSize < 10 || param.PageSize > 3000 {
		helper.RetData(ctx, false, "参数错误")
		return
	}

	s, err := model.GetLogList(param, ctx)
	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	helper.RetData(ctx, true, s)
}

// 弹窗公告管理
func (that *ServiceController) CustomServiceList(ctx *fasthttp.RequestCtx) {
	param := CustomServiceListParam{}

	err := json.Unmarshal(ctx.PostBody(), &param)

	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}
	if param.Page < 1 {
		param.Page = 1
	}
	if param.PageSize < 10 || param.PageSize > 3000 {
		helper.RetData(ctx, false, "参数错误")
		return
	}

	ex := g.Ex{}

	data, err := model.GetCustomServiceList(param.Page, param.PageSize, ex)
	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	helper.RetData(ctx, true, data)
}

// /更新弹窗
func (that *ServiceController) CustomServiceEdit(ctx *fasthttp.RequestCtx) {
	param := model.CustomserServiceItem{}

	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}
	model.InsertLog("客服配置编辑操作", ctx)
	err = model.EditGetCustomService(param)
	if err != nil {

		helper.RetData(ctx, false, helper.OperateFailed)
		return
	}
	helper.RetData(ctx, true, "成功")
}

// /客服删除
func (that *ServiceController) CustomServiceDelete(ctx *fasthttp.RequestCtx) {
	id := string(ctx.QueryArgs().Peek("id"))
	if !helper.CtypeDigit(id) {
		helper.RetData(ctx, false, helper.IDErr)
		return
	}
	model.InsertLog("客服配置删除操作", ctx)
	err := model.DeleteCustomService(id)
	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	helper.RetData(ctx, true, "成功")
}

func (that ServiceController) BroadcastList(ctx *fasthttp.RequestCtx) {
	param := model.BroadcasConfigParam{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {
		helper.RetData(ctx, false, "参数错误")
		return
	}
	s, err := model.GetBroadcastList(param, ctx)
	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	helper.RetData(ctx, true, s)
}

func (that ServiceController) UpdateBroadcastConfig(ctx *fasthttp.RequestCtx) {
	param := model.BroadcasConfig{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}
	model.InsertLog("滚屏配置更新", ctx)
	err = model.UpdateBroadcastConfig(param, 0)
	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	helper.RetData(ctx, true, "成功")
}

func (that ServiceController) DeleteBroadcastConfig(ctx *fasthttp.RequestCtx) {
	param := model.BroadcasConfig{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}
	model.InsertLog("滚屏配置删除", ctx)
	err = model.UpdateBroadcastConfig(param, 1)
	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	helper.RetData(ctx, true, "成功")
}
func (that *ServiceController) MailList(ctx *fasthttp.RequestCtx) {
	param := model.MailListParam{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {
		helper.RetData(ctx, false, "参数错误")
		return
	}
	if param.Page < 1 {
		param.Page = 1
	}
	if param.PageSize < 10 || param.PageSize > 3000 {
		helper.RetData(ctx, false, "参数错误")
		return
	}
	data, err := model.GetMailList(param)
	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	helper.RetData(ctx, true, data)
}

func (that *ServiceController) MailUpdate(ctx *fasthttp.RequestCtx) {
	param := model.MailItem{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {
		helper.RetData(ctx, false, "参数错误")
		return
	}
	admin := session.AdminGet(ctx)
	err = model.MailUpdate(param, admin["id"], admin["name"])
	if err != nil {
		helper.RetData(ctx, false, helper.OperateFailed)
		return
	}
	model.InsertLog("添加邮件发送", ctx)
	helper.RetData(ctx, true, "成功")
}

func (that *ServiceController) MailDelete(ctx *fasthttp.RequestCtx) {
	id := string(ctx.QueryArgs().Peek("id"))
	if !helper.CtypeDigit(id) {
		helper.RetData(ctx, false, helper.IDErr)
		return
	}
	model.InsertLog("邮件公告删除操作", ctx)
	err := model.MailDeleteById(id)
	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	helper.RetData(ctx, true, "成功")
}

func (this *ServiceController) UnbindControllerList(ctx *fasthttp.RequestCtx) {
	param := model.CommonParam{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}

	if param.Page < 1 {
		param.Page = 1
	}

	if param.PageSize < 10 || param.PageSize > 3000 {
		helper.RetData(ctx, false, "参数错误")
		return
	}

	s, err := model.GetUnbindControllerList(param, ctx)
	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	helper.RetData(ctx, true, s)
}

func (this *ServiceController) UnbindControllerInsert(ctx *fasthttp.RequestCtx) {
	param := model.UnbindControllerData{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}

	model.InsertLog("掉绑控制名单更新插入", ctx)

	userInfo, err := model.MemberFindByUid(param.Uid)
	auth, err := model.UserAuthCheck(userInfo, ctx)
	if auth == false || err != nil {
		helper.RetData(ctx, false, "非本渠道玩家")
		return
	}
	uid, _ := strconv.Atoi(param.Uid)
	if uid < 10000000 || uid > 100000000 {
		helper.RetData(ctx, false, "UID 错误")
		return
	}
	err = model.UpdateUnbindController(param, 0)
	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	helper.RetData(ctx, true, "成功")
}

func (this *ServiceController) UnbindControllerDelete(ctx *fasthttp.RequestCtx) {
	param := model.UnbindControllerData{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}
	model.InsertLog("掉绑控制名单删除", ctx)
	userInfo, err := model.MemberFindByUid(param.Uid)
	auth, err := model.UserAuthCheck(userInfo, ctx)
	if auth == false || err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}

	err = model.UpdateUnbindController(param, 1)
	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	helper.RetData(ctx, true, "成功")
}

func (this *ServiceController) ExcelOperatorandbusiness(ctx *fasthttp.RequestCtx) {
	loginuser := session.AdminGet(ctx)
	if loginuser["loginuser"] != "admin" {
		helper.RetData(ctx, false, "权限不足")
		return
	}

	exportData := model.ExcelOperatorAndBusiness()

	exportTitle := []string{
		"类型",
		"账户名称",
		"登陆账号",
		"充值手续费比例",
		"提现手续费比例",
		"API费用",
		"谷歌验证码",
		"账号类型（仅业务员）",
		"所属渠道（仅业务员）",
		"所属业务员（仅业务员）",
	}
	filename := "渠道业务员列表-" + time.Now().Format("20060102150405")
	if model.ExportExcel(filename, exportTitle, exportData) == nil {
		helper.RetData(ctx, true, filename)
		return
	} else {
		helper.RetData(ctx, false, helper.RequestFail)
		return
	}
}

func (this *ServiceController) IntoOperatorandbusiness(ctx *fasthttp.RequestCtx) {
	admin := session.AdminGet(ctx)
	if admin["loginuser"] != "admin" {
		helper.RetData(ctx, false, "权限不足")
		return
	}
	password := strings.TrimSpace(string(ctx.FormValue("password")))
	if model.ValidatePassword(password) == false {
		helper.RetData(ctx, false, "密码至少8位数，大、小写英文字母+数字组合")
		return
	}
	fh, err := ctx.FormFile("uploadfile")
	if err != nil {
		helper.RetData(ctx, false, "Upload error")
		return
	}

	// 校验扩展名
	ext := filepath.Ext(fh.Filename)
	if ext != ".xlsx" && ext != ".xls" {
		helper.RetData(ctx, false, helper.ParamNull)
		return
	}

	// 保存上传的文件到临时文件
	file, err := fh.Open()
	if err != nil {
		helper.RetData(ctx, false, "Cannot open uploaded file")
		return
	}
	defer file.Close()

	tmpFile, err := os.CreateTemp("", "upload-*.xlsx") // 这里只处理 .xlsx 文件
	if err != nil {
		helper.RetData(ctx, false, "Cannot create temp file")
		return
	}
	defer os.Remove(tmpFile.Name()) // 处理完删除临时文件
	defer tmpFile.Close()

	// 将上传文件的内容写入临时文件
	_, err = io.Copy(tmpFile, file)
	if err != nil {
		helper.RetData(ctx, false, "Cannot save uploaded file")
		return
	}

	// 使用 excelize 打开临时文件
	f, err := excelize.OpenFile(tmpFile.Name())
	if err != nil {
		fmt.Println(err)
		helper.RetData(ctx, false, "Cannot open Excel file")
		return
	}
	op_count := 0
	bu_count := 0
	// 遍历 Sheet
	sheets := f.GetSheetMap()
	for _, sheet := range sheets {
		//fmt.Println("Sheet:", sheet)
		rows := f.GetRows(sheet)
		if err != nil {
			fmt.Println("Error reading rows:", err)
			continue
		}
		if len(rows) <= 1 {
			fmt.Println("No data rows")
			continue
		}

		for _, row := range rows[1:] {

			//先导入渠道
			if row[0] == "业务员" {
				continue
			}

			operator, _ := model.GetOperatorInfoByUsername(row[1])
			if operator.Id != "" {
				continue
			}

			operator.OperatorName = row[1]
			operator.Password = password
			operator.RechargeFee, _ = strconv.ParseFloat(row[3], 64)
			operator.WithdrawFee, _ = strconv.ParseFloat(row[4], 64)
			operator.ApiFee = row[5]
			operator.Seamo = row[6]
			operator.WithdrawButton = "0"
			operator.AccountSecurity = 0
			operator.IntoFakepgRate = 100

			model.MerchantAdd(admin["name"], admin["id"], operator)
			op_count += 1
		}
		for _, row := range rows[1:] {
			//再导入业务员
			if row[0] == "渠道" {
				continue
			}
			business, _ := model.GetBusinessInfoByLoginAccount(row[2])
			if business.Id != "" {
				continue
			}
			business.AccountName = row[1]
			business.LoginAccount = row[2]
			business.Password = password
			business.RechargeFee, _ = strconv.ParseFloat(row[3], 64)
			business.WithdrawFee, _ = strconv.ParseFloat(row[4], 64)
			business.Seamo = row[6]
			business.ApiFee = row[5]
			business.Type = row[7]
			business.State = "1"
			operator, _ := model.GetOperatorInfoByUsername(row[8])
			if operator.Id == "" {
				operator.Id = "888888"
			}
			business.OperatorId = operator.Id
			parent, _ := model.GetBusinessInfoByLoginAccount(row[9])
			business.ParentId = parent.Id
			business.ParentName = parent.LoginAccount
			model.BusinessInsert(business)
			bu_count += 1
		}
	}

	helper.RetData(ctx, true, "成功导入渠道："+strconv.Itoa(op_count)+"个，业务员："+strconv.Itoa(bu_count)+"个")
	return
}
